create or replace function pgds_gen_bytea(len int) returns bytea as $$
declare message bytea;
declare i int;
begin
        i := 0;
        message := '';
        loop
                message := message || ' ';
                message := set_byte(message, i, (0 + (random()*255)::int));
                i := i + 1;
                if i >= len then
                        exit;
                end if;
        end loop;
	return message;
end;
$$ language plpgsql;

create or replace function pgds_test_dsa(nbits int, len int) returns int as $$
declare message bytea;
declare signature bytea;
declare private_key text;
declare public_key text;
declare r record;
begin
        private_key := gen_keys_pair('dsa', nbits);
        if private_key = '' then
                return 1;
        end if;
        public_key := get_public_key(private_key);
        if public_key = '' then
                return 2;
        end if;
        message := pgds_gen_bytea(len);
        for r in select alg from regexp_split_to_table('dsa/dss1', E'\\s+') as alg loop
		signature := sign(r.alg, private_key, message);
		if signature = '' then
			return 3;
		end if;
		if signature = message then
			return 4;
		end if;
		if verify(r.alg, public_key, message, signature) <> 0 then
			return 5;
		end if;
        end loop;
        return 0;
end;
$$ language plpgsql;


select * from (
      select 1 as test, pgds_test_dsa(512, 128) as rc
union select 2 as test, pgds_test_dsa(512, 256) as rc
union select 3 as test, pgds_test_dsa(512, 384) as rc
union select 4 as test, pgds_test_dsa(512, 512) as rc
union select 5 as test, pgds_test_dsa(512, 1024) as rc
union select 6 as test, pgds_test_dsa(512, 2048) as rc
union select 7 as test, pgds_test_dsa(512, 4096) as rc
union select 8 as test, pgds_test_dsa(512, 8192) as rc
union select 9 as test, pgds_test_dsa(512, 16384) as rc
union select 10 as test, pgds_test_dsa(1024, 128) as rc
union select 11 as test, pgds_test_dsa(1024, 256) as rc
union select 12 as test, pgds_test_dsa(1024, 384) as rc
union select 13 as test, pgds_test_dsa(1024, 512) as rc
union select 14 as test, pgds_test_dsa(1024, 1024) as rc
union select 15 as test, pgds_test_dsa(1024, 2048) as rc
union select 16 as test, pgds_test_dsa(1024, 4096) as rc
union select 17 as test, pgds_test_dsa(1024, 8192) as rc
union select 18 as test, pgds_test_dsa(1024, 16384) as rc
union select 19 as test, pgds_test_dsa(2048, 128) as rc
union select 20 as test, pgds_test_dsa(2048, 256) as rc
union select 21 as test, pgds_test_dsa(2048, 384) as rc
union select 22 as test, pgds_test_dsa(2048, 512) as rc
union select 23 as test, pgds_test_dsa(2048, 1024) as rc
union select 24 as test, pgds_test_dsa(2048, 2048) as rc
union select 25 as test, pgds_test_dsa(2048, 4096) as rc
union select 26 as test, pgds_test_dsa(2048, 8192) as rc
union select 27 as test, pgds_test_dsa(2048, 16384) as rc
) s1 order by s1.test
;

drop function pgds_gen_bytea(len int);
drop function pgds_test_dsa(nbits int, len int);

